package handler

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"myai/core"
	"myai/core/types"
	"myai/service"
	"myai/store/model"
	"myai/store/model/req"
	"myai/utils"
	"myai/utils/resp"
	"strings"
)

// PromptHandler 提示词生成
// 使用AI生成绘画指令、歌词、视频生成指令等
type PromptHandler struct {
	BaseHandler
	userService *service.UserService
}

func NewPromptHandler(app *core.AppServer, db *gorm.DB, userService *service.UserService) *PromptHandler {
	return &PromptHandler{
		BaseHandler: BaseHandler{App: app, DB: db},
		userService: userService,
	}
}

// Lyric godoc
// @Summary      歌词提示词生成
// @Description  歌词提示词生成
// @Tags         提示词生成
// @Accept       json
// @Produce      json
// @Param        req   body     req.PromptGenerateReq  true  "提示词信息"
// @Success      200  {object}  types.BizVo{data=string}
// @Router       /api/prompt/lyric [post]
// @Security ApiKeyAuth
func (h *PromptHandler) Lyric(c *gin.Context) {
	var data req.PromptGenerateReq
	if err := c.ShouldBindJSON(&data); err != nil {
		resp.ERROR(c, types.InvalidArgs)
		return
	}
	content, err := utils.OpenAIRequest(h.DB, fmt.Sprintf(service.LyricPromptTemplate, data.Prompt), h.App.SysConfig.TranslateModelId)
	if err != nil {
		resp.ERROR(c, "生成歌词提示词失败："+err.Error())
		return
	}

	// 扣减算力
	if h.App.SysConfig.PromptPower > 0 {
		userId := h.GetLoginUserId(c)
		h.userService.DecreasePower(int(userId), h.App.SysConfig.PromptPower, model.PowerLog{
			Type:   types.PowerConsume,
			Model:  h.getPromptModel(),
			Remark: "生成歌词",
		})
	}

	resp.SUCCESS(c, content)
}

// Image godoc
// @Summary      生成 AI 绘画提示词
// @Description  生成 AI 绘画提示词
// @Tags         提示词生成
// @Accept       json
// @Produce      json
// @Param        req   body     req.PromptGenerateReq  true  "提示词信息"
// @Success      200  {object}  types.BizVo{data=string}
// @Router       /api/prompt/image [post]
// @Security ApiKeyAuth
func (h *PromptHandler) Image(c *gin.Context) {
	var data req.PromptGenerateReq
	if err := c.ShouldBindJSON(&data); err != nil {
		resp.ERROR(c, types.InvalidArgs)
		return
	}
	content, err := utils.OpenAIRequest(h.DB, fmt.Sprintf(service.ImagePromptOptimizeTemplate, data.Prompt), h.App.SysConfig.TranslateModelId)
	if err != nil {
		resp.ERROR(c, "生成 AI 绘画提示词失败："+err.Error())
		return
	}

	// 扣减算力
	if h.App.SysConfig.PromptPower > 0 {
		userId := h.GetLoginUserId(c)
		h.userService.DecreasePower(int(userId), h.App.SysConfig.PromptPower, model.PowerLog{
			Type:   types.PowerConsume,
			Model:  h.getPromptModel(),
			Remark: "生成绘画提示词",
		})
	}

	resp.SUCCESS(c, strings.Trim(content, `"`))
}

// Video godoc
// @Summary      生成视频提示词
// @Description  生成视频提示词
// @Tags         提示词生成
// @Accept       json
// @Produce      json
// @Param        req   body     req.PromptGenerateReq  true  "提示词信息"
// @Success      200  {object}  types.BizVo{data=string}
// @Router       /api/prompt/video [post]
// @Security ApiKeyAuth
func (h *PromptHandler) Video(c *gin.Context) {
	var data req.PromptGenerateReq
	if err := c.ShouldBindJSON(&data); err != nil {
		resp.ERROR(c, types.InvalidArgs)
		return
	}
	content, err := utils.OpenAIRequest(h.DB, fmt.Sprintf(service.VideoPromptTemplate, data.Prompt), h.App.SysConfig.TranslateModelId)
	if err != nil {
		resp.ERROR(c, "生成视频提示词失败："+err.Error())
		return
	}
	// 扣减算力
	if h.App.SysConfig.PromptPower > 0 {
		userId := h.GetLoginUserId(c)
		h.userService.DecreasePower(int(userId), h.App.SysConfig.PromptPower, model.PowerLog{
			Type:   types.PowerConsume,
			Model:  h.getPromptModel(),
			Remark: "生成视频脚本",
		})
	}
	resp.SUCCESS(c, strings.Trim(content, `"`))
}

// MetaPrompt godoc
// @Summary      生成元提示词
// @Description  生成元提示词
// @Tags         提示词生成
// @Accept       json
// @Produce      json
// @Param        req   body     req.PromptGenerateReq  true  "提示词信息"
// @Success      200  {object}  types.BizVo{data=string}
// @Router       /api/prompt/meta [post]
// @Security ApiKeyAuth
func (h *PromptHandler) MetaPrompt(c *gin.Context) {
	var data req.PromptGenerateReq
	if err := c.ShouldBindJSON(&data); err != nil {
		resp.ERROR(c, types.InvalidArgs)
		return
	}

	messages := make([]interface{}, 0)
	messages = append(messages, types.Message{
		Role:    "system",
		Content: service.MetaPromptTemplate,
	})
	messages = append(messages, types.Message{
		Role:    "user",
		Content: "Task, Goal, or the Role to actor is:\n" + data.Prompt,
	})
	content, err := utils.SendOpenAIMessage(h.DB, messages, 0)
	if err != nil {
		resp.ERROR(c, "生成元提示词失败："+err.Error())
		return
	}
	resp.SUCCESS(c, strings.Trim(content, `"`))
}

func (h *PromptHandler) getPromptModel() string {
	if h.App.SysConfig.TranslateModelId > 0 {
		var chatModel model.ChatModel
		h.DB.Where("id", h.App.SysConfig.TranslateModelId).First(&chatModel)
		return chatModel.Value
	}
	return "gpt-4o"
}